package fr.insalyon.sims.broadcast.tests;

import java.io.IOException;
import java.net.InetAddress;
import java.util.HashMap;

import fr.insalyon.sims.broadcast.network.DataErrorEvent;
import fr.insalyon.sims.broadcast.network.DataErrorListener;
import fr.insalyon.sims.broadcast.network.DataEvent;
import fr.insalyon.sims.broadcast.network.DataListener;
import fr.insalyon.sims.broadcast.network.TCPStreamReceiver;
import fr.insalyon.sims.broadcast.network.TCPStreamTransmitter;
import fr.insalyon.sims.broadcast.service.BroadcastReceiverService;
import fr.insalyon.sims.broadcast.service.BroadcastTransmitterService;
import fr.insalyon.sims.streamManagerClient.Response;

public class ServicesTest {
	// ------------------------------------------------------- CONSTANTS -- //
	// ------------------------------------------------------ ATTRIBUTES -- //
	// ---------------------------------------------------- CONSTRUCTORS -- //
	// --------------------------------------------------------- METHODS -- //

	public static void main(String[] args) throws IOException {
		int srcPort = 22593;
		int destPort = 22594;
		String multicastIp = "224.0.0.1";
		int multicastPort = 22594;
		
		final StringBuffer receivedData = new StringBuffer();
		
		// Create TCP receiver stream
		TCPStreamReceiver receiver = new TCPStreamReceiver(destPort);
		receiver.addDataListener(new DataListener() {
			public void dataReceived(DataEvent event) {
				System.out.println("[receiver] data received");
				String data = new String(event.getData(), event.getOffset(), event.getLength());
				receivedData.append(data);
			}
		});
		receiver.addDataErrorListener(new DataErrorListener() {
			public void streamError(DataErrorEvent event) {
				System.out.println("[receiver] an exception occured!");
				event.getException().printStackTrace();
			}
		});
		
		// Start the stream
		receiver.connect();
		receiver.start();
		System.out.println("[receiver] started");
		
		// Receiver service parameters
		HashMap<String, String> receiverParams = new HashMap<String, String>();
		receiverParams.put("destIp", "127.0.0.1");
		receiverParams.put("destPort", String.valueOf(destPort));
		receiverParams.put("multicastIp", multicastIp);
		receiverParams.put("multicastPort", String.valueOf(multicastPort));
		
		// Create and start the receiver service
		BroadcastReceiverService receiverService = new BroadcastReceiverService();
		Response receiverResponse = receiverService.doStart(receiverParams);
		System.out.println("[receiverService] started (response: " + receiverResponse + ")");
		
		// Transmitter service parameters
		HashMap<String, String> params = new HashMap<String, String>();
		params.put("multicastIp", multicastIp);
		params.put("multicastPort", String.valueOf(multicastPort));
		
		// Create and start the transmitter service
		BroadcastTransmitterService transmitterService =
			new BroadcastTransmitterService(srcPort,
					InetAddress.getByName(multicastIp), multicastPort);
		Response transmitterResponse = transmitterService.doStart(params);
		System.out.println("[transmitterService] started (response: " + transmitterResponse + ")");

		// Create TCP transmitter stream
		TCPStreamTransmitter transmitter = new TCPStreamTransmitter(InetAddress.getLocalHost(), srcPort);
		transmitter.addDataErrorListener(new DataErrorListener() {
			public void streamError(DataErrorEvent event) {
				System.out.println("[transmitter] an exception occured!");
				event.getException().printStackTrace();
			}
		});
		
		// Start the stream
		transmitter.connect();
		transmitter.start();
		System.out.println("[transmitter] started");
		
		StringBuffer sentData = new StringBuffer();
		
		// Send an hello world every 2 seconds
		for (int i = 0; i < 100; i++) {
			String data = i + " - hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !hello world !";
			sentData.append(data);
			
			transmitter.send(data.getBytes(), 0, data.length());
			
			System.out.println("[transmitter] hello world sent");
		}
		
		try {
			Thread.sleep(5000);
		} catch (InterruptedException e) {
			// Ignored
		}
		
		// Stop streams
		transmitter.stop();
		transmitter.disconnect();
		System.out.println("[transmitter] stopped");
		transmitterResponse = transmitterService.doStop();
		System.out.println("[transmitterService] stopped (response: " + transmitterResponse + ")");
		receiverResponse = receiverService.doStop();
		System.out.println("[receiverService] stopped (response: " + transmitterResponse + ")");
		receiver.stop();
		System.out.println("[receiver] stopped");
		
		System.out.println("sent == received ? " + sentData.toString().equals(receivedData.toString()));
	}
	
	// ------------------------------------------------- PRIVATE METHODS -- //
	// --------------------------------------------------- INNER CLASSES -- //
}
